﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration;
using System.IO;

namespace FileDFS.Utils.PathConfig
{
    /*
     * Coder:Tieria
     * WriteTime:2015.5.13
     * FileName:FileExtensionEnum.cs
     * ReMark:文件类型枚举,因为限制,只能上传几种类型,不在此范围的将不能上传
     */
    public class PathHandler
    {
        public static PathHandler GetInstance()
        {
            return new PathHandler();
        }


        #region 获取目录配置的根节点
        /// <summary>
        /// 获取目录配置的根节点配置
        /// </summary>
        /// <returns></returns>
        public AllPathConfig GetAllFilePath()
        {
            AllPathConfig config = (AllPathConfig)ConfigurationManager.GetSection("AllPathConfig");
            return config;
        }
        #endregion

        #region 根据传递的枚举类型获取 PathOption
        /// <summary>
        /// 根据传递的枚举类型获取PathOption
        /// </summary>
        /// <param name="getEnum"></param>
        /// <returns></returns>
        public List<PathOption> GetOptions(OptionGetEnum getEnum)
        {
            AllPathConfig config = GetAllFilePath();
            IEnumerable<PathOption> ieQuery;
            switch (getEnum)
            {
                case OptionGetEnum.ImagePublic:
                default:
                    ieQuery = from p in config.imagePathConfig.publicPath.optionsCollection.Cast<PathOption>() select p;
                    break;
                case OptionGetEnum.ImagePrivate:
                    ieQuery = from p in config.imagePathConfig.privatePath.optionsCollection.Cast<PathOption>() select p;
                    break;
                case OptionGetEnum.FilePrivate:
                    ieQuery = from p in config.filePathConfig.privatePath.optionsCollection.Cast<PathOption>() select p;
                    break;
            }
            return ieQuery.ToList();
        }
        #endregion

        #region 将PathOption转换成PathDetail
        /// <summary>
        /// 将PathOption转换成PathDetail
        /// </summary>
        /// <param name="pathOption">pathOption</param>
        /// <returns>PathDetail</returns>
        public PathDetail GetDetailByPathOption(PathOption pathOption)
        {
            PathDetail pathDetail = new PathDetail();
            pathDetail.Virtual_FullPath = PathHelper.CombineRelativePath(pathOption.VirtualPath);
            pathDetail.Absolute_FullPath = Path.Combine(PathHelper.CombineDriverAbsolute(pathOption.AbsoluteDriver, pathOption.AbsolutePath));

            return pathDetail;
        } 
        #endregion

        #region 根据PathOption的参数获取某个目录下的详细目录,并且按照名称进行了到序
        /// <summary>
        /// 根据PathOption的参数获取某个目录下的详细目录
        /// </summary>
        /// <param name="pathOption">PathOption参数</param>
        /// <returns>List<PathOption>的集合</returns>
        public List<PathOption> GetCatalogByPathOption(PathOption pathOption)
        {
            List<PathOption> optionList = new List<PathOption>();
            //根据Option获取 PathDetail的详情
            PathDetail pathDetail = GetDetailByPathOption(pathOption);
            //获取低下所有的目录,并且转换成List<PathOption>
            DirectoryInfo directoryInfo = new DirectoryInfo(pathDetail.Absolute_FullPath);
            var dirs = directoryInfo.GetDirectories().OrderByDescending(x => x.Name);
            foreach (var item in dirs)
            {
                PathOption option = new PathOption();
                option.AbsoluteDriver = pathOption.AbsoluteDriver;
                option.AbsolutePath = Path.Combine(pathOption.AbsolutePath, item.Name);
                option.VirtualPath = PathHelper.CombineRelativePath(pathOption.VirtualPath, item.Name);
                optionList.Add(option);
            }
            return optionList;
        }
        #endregion

        public PathOption GetCurrentPathOption(OptionGetEnum getEnum)
        {
            PathOption pathOption = new PathOption();
            List<PathOption> rootOptionList = GetOptions(getEnum).ToList();
            //随机取得当前配制文件中的随意一个目录
            Random rd = new Random();
            int currentIndex = rd.Next(0, rootOptionList.Count);
            // 根目录 的PathOption
            PathOption rootOption = rootOptionList[currentIndex];
            PathDetail detail = GetDetailByPathOption(rootOption);
            //根目录是否存在，不存在就创建
            Directory.CreateDirectory(Path.GetDirectoryName(detail.Absolute_FullPath));
            //一级目录,在根目录下判断一级目录是否存满
            PathOption optionOne = CreateSonIfNotExist(rootOption);
            if (optionOne == null)
            {

            }

            return pathOption;
        }

        #region 查看子目录,如果不存在则创建，存在则返回第一个
        public PathOption CreateSonIfNotExist(PathOption pathOption)
        {
            List<PathOption> pathList = GetCatalogByPathOption(pathOption);
            if (pathList.Count <= 0)
            {
                PathDetail detail = GetDetailByPathOption(pathOption);
                //子文件夹的目录为OA开始
                string beginCatalog = "OA";
                string sonPath = Path.Combine(pathOption.AbsolutePath, beginCatalog);
                Directory.CreateDirectory(sonPath);
                PathOption createOption = new PathOption()
                {
                    AbsoluteDriver = pathOption.AbsoluteDriver,
                    AbsolutePath = Path.Combine(pathOption.AbsolutePath, beginCatalog),
                    VirtualPath = PathHelper.CombineRelativePath(pathOption.VirtualPath, beginCatalog)
                };
                return createOption;
            }
            else
            {
                //判断该目录下的子目录是否已经达到了最大
                if (IsMaxCatalog(pathOption))
                {
                    return null;
                }
                else
                {
                    return pathList.FirstOrDefault();
                }
            }
        } 
        #endregion


        

        #region 判断某个 一级目录下的二级目录是否饱和 >根目录>一级目录>二级目录
        /// <summary>
        /// 判断某个 一级目录下的二级目录是否饱和
        /// </summary>
        /// <param name="pathOption">一级目录</param>
        /// <returns></returns>
        private bool IsMaxCatalog(PathOption pathOption)
        {
            PathDetail detail = GetDetailByPathOption(pathOption);
            int count = Directory.GetDirectories(detail.Absolute_FullPath).Count();
            if (count > 26 * 10)
            {
                return true;
            }
            return false;
        }
        #endregion

        #region 判断二级目录是否已经装满
        private bool IsMaxFile(PathOption pathOption)
        {
            PathDetail detail = GetDetailByPathOption(pathOption);
            int count = Directory.GetFiles(detail.Absolute_FullPath).Count();
            if (count > 200)
            {
                return true;
            }
            return false;
        } 
        #endregion



    }
}
